﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity;

namespace Arch.Intercep.CallHandlers
{
    public class ActionInterceptionHandler : ICallHandler
    {
        public ActionInterceptionHandler SetTargets(ActionTarget beforeTarget, ActionTarget afterTarget)
        {
            BeforeActionTarget = beforeTarget;
            AfterActionTarget = afterTarget;
            return this;
        }

        [Dependency]
        public IInterceptorManager Interceptor { get; set; }

        public ActionTarget BeforeActionTarget { get; set; }
        public ActionTarget AfterActionTarget { get; set; }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            if (input.Arguments.Count > 0)
            {
                foreach (var entity in GetArguments(input.Arguments.Cast<object>().First()))
                {
                    if(entity != null)
                        Interceptor.Intercept(entity, BeforeActionTarget);
                }
            }
            
            var next = getNext()(input, getNext);

            if (next.ReturnValue != null)
            {
                foreach (var entity in GetArguments(next.ReturnValue))
                {
                    Interceptor.Intercept(entity, AfterActionTarget);
                }
            }
            return next;
        }

        private static IEnumerable GetArguments(object source)
        {
            IEnumerable entities;
            if (source is IEnumerable)
                entities = (IEnumerable)source;
            else
                entities = new object[] { source };
            return entities;
        }

        public int Order { get; set; }
    }
}
